package top.frsf.music;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import javax.sound.sampled.*;
import java.io.File;
import java.io.IOException;

/**
 * 简单音乐播放器 - 新增音量控制
 *
 * @author FRSF
 * @since 2025/8/1 11:05
 */
@Data
@Slf4j
public class SimpleMusicPlayer implements Runnable {
    /**
     * 音乐文件路径
     */
    private String musicFilePath;
    /**
     * 音量 0-100
     */
    private int volume = 100;
    private volatile boolean isPlaying = false;
    private Clip clip;

    public SimpleMusicPlayer(String musicFilePath) {
        this.musicFilePath = musicFilePath;
    }

    public SimpleMusicPlayer(String musicFilePath, int volume) {
        this(musicFilePath);
        setVolume(volume);
    }

    @Override
    public void run() {
        playMusic();
    }

    /**
     * 播放音乐（循环播放）
     */
    private void playMusic() {
        try {
            File musicFile = new File(musicFilePath);
            AudioInputStream audioInputStream = AudioSystem.getAudioInputStream(musicFile);
            clip = AudioSystem.getClip();
            clip.open(audioInputStream);

            // 设置音量
            applyVolume();

            isPlaying = true;

            // 循环播放
            clip.loop(Clip.LOOP_CONTINUOUSLY);

            // 保持线程运行直到程序结束
            while (isPlaying) {
                Thread.sleep(1000); // 每秒检查一次
            }

        } catch (UnsupportedAudioFileException | IOException | LineUnavailableException e) {
            log.error("音乐播放出错", e);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        } finally {
            // 释放资源
            if (clip != null) {
                clip.close();
            }
        }
    }

    /**
     * 设置音量 (0-100百分比)
     *
     * @param volume 音量百分比 (0 - 100)
     */
    public void setVolume(int volume) {
        this.volume = Math.max(0, Math.min(100, volume)); // 限制音量范围在0-100
        applyVolume();
    }

    /**
     * 应用音量设置到音频播放器
     */
    private void applyVolume() {
        if (clip != null && clip.isControlSupported(FloatControl.Type.MASTER_GAIN)) {
            FloatControl gainControl = (FloatControl) clip.getControl(FloatControl.Type.MASTER_GAIN);

            // 将0-100范围转换为dB值
            float dB = volume == 0
                    ? gainControl.getMinimum() // 静音
                    : (float) (Math.log10(volume / 100.0) * 20); // 对数转换使音量变化更自然

            // 确保dB值在有效范围内
            dB = Math.max(gainControl.getMinimum(), Math.min(gainControl.getMaximum(), dB));
            gainControl.setValue(dB);
        }
    }

    /**
     * 创建并启动播放线程
     *
     * @return 启动的线程实例
     */
    public Thread createAndStartThread() {
        Thread thread = new Thread(this);
        thread.setDaemon(true); // 设置为守护线程，主程序退出时自动结束
        thread.start();
        return thread;
    }

    /**
     * 停止音乐播放并释放资源
     */
    public void stop() {
        isPlaying = false;

        if (clip != null) {
            clip.stop();
            clip.close();
        }
    }

    /**
     * 检查是否正在播放
     *
     * @return 是否正在播放
     */
    public boolean isPlaying() {
        return isPlaying;
    }
}
